#ifndef COCOSDIALOG_H_20111117
#define COCOSDIALOG_H_20111117

#include "cocos2d.h"
#include "CocosUIBase.h"
#include "CocosButton.h"
#include "CocosSlide.h"

#include <list>
#include <vector>
#include <algorithm>

typedef vector<CSpriteButton *> BtnVector;
typedef list<CSpriteButton *> BtnList;
class CCocosDialog : public CCocosUIBase
{
public:
	enum PopStyle
	{
		POP_NONE,
		POP_SIMPLE,
		POP_ElasticOut,
		POP_SCALEBIG,
		POP_MOVETO
	};
	enum ShutStyle
	{
		SHUT_NONE,
		SHUT_FadeOutBig,
		SHUT_FadeOutSmall,
		SHUT_MOVETO
	};

private:
	virtual void onReceiveNewTouch();
	virtual void onCurTouchMoveOut();
	virtual void onCurTouchDisable();
	LAYER_NODE_FUNC(CCocosDialog);
public:
	static CCocosDialog *CreateDialog(int id, CUIListener *pListener);

	CCocosDialog()
		, m_pTarget(NULL)
		, m_selector(NULL)
		, m_pSprBack(NULL)
		, m_actionDelay(0.5f)
		, m_ptMoveTo(0, 0)
	{

	}

	bool Create(cocos2d::CCNode *pParent, int zOrder, cocos2d::CCPoint ptPos, const char *szBack, bool bUseCache = false)
	{
		if(NULL == pParent)
		{
			return false;
		}
		m_pParent = pParent;
		if(bUseCache)
		{
			m_pSprBack = CCSprite::spriteWithSpriteFrameName(szBack);
		}
		else
		{
			m_pSprBack = CCSprite::spriteWithFile(szBack);
		}

		if(NULL == m_pSprBack)
		{
			return false;
		}
		
		m_pSprBack->setPosition(ptPos);
		m_bVisible = false;
		m_pSprBack->setIsVisible(m_bVisible);
		m_zorder = zOrder;
		m_pParent->addChild(m_pSprBack, m_zorder);
		m_bEnable = true;
		return true;
	}

	CSpriteButton *AddButton(int id, CButtonListener *pListener, cocos2d::CCPoint ptPos, const char *szImage, int zOrder = 0, bool bUseCache = false, 
				   CSpriteButton::ButtonType type = CSpriteButton::TYPE_SCALE, const char *szFileName = NULL)
	{
		if(!m_bEnable || NULL == pListener)
		{
			return NULL;
		}
		
		CSpriteButton *pNewBtn;
		if(bUseCache)
		{
			pNewBtn = CSpriteButton::spriteWithSpriteFrameName(szImage);
		}
		else
		{
			pNewBtn = CSpriteButton::spriteWithFile(szImage);
		}

		if(NULL == pNewBtn)
		{
			return NULL;
		}

		pNewBtn->setPosition(ptPos);

		m_pSprBack->addChild(pNewBtn, zOrder);
		pNewBtn->SetData(id, pListener, type, szFileName, bUseCache);
		

		m_vBtns.push_back(pNewBtn);
		
		return pNewBtn;
	}

	CCocosSlide *AddSlide(int id , CButtonListener *pListener, const cocos2d::CCRect &rc, bool bUseFrame, 
		const char *szBarName, const char *szBtnName  = NULL  , const char *szBackName  = NULL )
	{
		CCocosSlide *pNewSlide = CCocosSlide::CreateSlide(m_pSprBack, 0, id, pListener, rc, bUseFrame, szBarName, szBtnName, szBackName);

		if(NULL != pNewSlide)
		{
			m_vSlide.push_back(pNewSlide);
		}

		return pNewSlide;
	}

	void HideButton(int id)
	{
		for(BtnVector::iterator iterBtn = m_vBtns.begin(); iterBtn != m_vBtns.end(); iterBtn++)
		{
			if((*iterBtn)->GetID() == id)
			{
				if(find(m_listIterBtn.begin(), m_listIterBtn.end(), *iterBtn) == m_listIterBtn.end())
				{
					m_listIterBtn.push_back(*iterBtn);
				}
				(*iterBtn)->setIsVisible(false);
				(*iterBtn)->SetIsEnable(false);
			}
		}
	}

	void ShowButton(int id)
	{
		
		for(BtnList::iterator iterIter = m_listIterBtn.begin(); iterIter != m_listIterBtn.end();iterIter++)
		{
			if((*iterIter)->GetID() == id)
			{
				(*iterIter)->setIsVisible(true);
				(*iterIter)->SetIsEnable(true);
				m_listIterBtn.erase(iterIter);

				return;
			}
		}
		

		
	}

	void ShowCallButton(int id)
	{
		for(BtnVector::iterator iter = m_vBtns.begin(); iter != m_vBtns.end(); iter++)
		{
			if((*iter)->GetID() == id && (*iter)->GetType() == CSpriteButton::TYPE_CALLSHOW)
			{
				(*iter)->setIsVisible(true);
			}
		}
	}

	void HideCallButton(int id)
	{
		for(BtnVector::iterator iter = m_vBtns.begin(); iter != m_vBtns.end(); iter++)
		{
			if((*iter)->GetID() == id && (*iter)->GetType() == CSpriteButton::TYPE_CALLSHOW)
			{
				(*iter)->setIsVisible(false);
			}
		}
	}

	bool Pop(PopStyle style = POP_SIMPLE)
	{
		if(!m_bEnable)
		{
			return false;
		}

		m_pSprBack->setScale(1.0f);
		m_pSprBack->setOpacity(255);
		for(vector<CSpriteButton *>::iterator iterBtn = m_vBtns.begin(); iterBtn != m_vBtns.end(); iterBtn++)
		{
			if(find(m_listIterBtn.begin(), m_listIterBtn.end(), *iterBtn) == m_listIterBtn.end())
			{
				(*iterBtn)->stopAllActions();
				if((*iterBtn)->GetType() != CSpriteButton::TYPE_TRANSPARENT && (*iterBtn)->GetType() != CSpriteButton::TYPE_CALLSHOW)
				{
					(*iterBtn)->setIsVisible(true);
				}
				
				(*iterBtn)->setScale(1.0f);
				(*iterBtn)->setOpacity(255);
			}
		}
		m_pSprBack->setIsVisible(true);

		switch(style)
		{
		case POP_NONE:
			{
				;
			}
			break;
		case POP_SIMPLE:
			{
				OnPop();
			}
			break;
		case POP_ElasticOut:
			{
				m_pSprBack->setScale(0.01f);
				m_pSprBack->runAction(CCSequence::actions(
					CCEaseElasticOut::actionWithAction(CCScaleTo::actionWithDuration(m_actionDelay, 1.0f, 1.0f)),
					CCCallFunc::actionWithTarget(this, callfunc_selector(CCocosDialog::OnPop)),
					NULL));

			}
			break;

		case POP_SCALEBIG:
			{
				m_pSprBack->setScale(0.01f);
				m_pSprBack->runAction(CCSequence::actions(
					CCScaleTo::actionWithDuration(m_actionDelay, 1.0f, 1.0f),
					CCCallFunc::actionWithTarget(this, callfunc_selector(CCocosDialog::OnPop)),
					NULL));

			}
			break;

		case POP_MOVETO:
			{
				m_pSprBack->runAction(CCSequence::actions(
					CCMoveTo::actionWithDuration(m_actionDelay, m_ptMoveTo),
					CCCallFunc::actionWithTarget(this, callfunc_selector(CCocosDialog::OnPop)),
					NULL));

			}
		}

		return true;
	}

	void Shut(ShutStyle style = SHUT_NONE)
	{
		if(!m_bEnable)
		{
			return;
		}

		EnableButtons(false);

		switch(style)
		{
		case SHUT_NONE:
			{
				if(NULL != m_pTarget)
				{
					m_pSprBack->runAction(CCSequence::actions(
                                                              CCCallFunc::actionWithTarget(this, callfunc_selector(CCocosDialog::OnShut)),
                                                              CCCallFunc::actionWithTarget(m_pTarget, m_selector),
                                                              NULL));
				}
				else
				{
					m_pSprBack->runAction(CCSequence::actions(
                                                              CCCallFunc::actionWithTarget(this, callfunc_selector(CCocosDialog::OnShut)),
                                                              NULL));

				}
			}
			break;

		case SHUT_FadeOutBig:
			{
				if(NULL != m_pTarget)
				{
					m_pSprBack->runAction(CCSequence::actions(
						CCFadeOut::actionWithDuration(m_actionDelay),
						CCCallFunc::actionWithTarget(this, callfunc_selector(CCocosDialog::OnShut)),
						CCCallFunc::actionWithTarget(m_pTarget, m_selector),
						NULL));
					m_pTarget = NULL;
				}
				else
				{
					m_pSprBack->runAction(CCSequence::actions(
						CCFadeOut::actionWithDuration(m_actionDelay),
						CCCallFunc::actionWithTarget(this, callfunc_selector(CCocosDialog::OnShut)),
						NULL));
				}

				m_pSprBack->runAction(CCScaleTo::actionWithDuration(m_actionDelay, 2.0f, 2.0f));

				for(vector<CSpriteButton *>::iterator iterBtn = m_vBtns.begin(); iterBtn != m_vBtns.end(); iterBtn++)
				{
					if(find(m_listIterBtn.begin(), m_listIterBtn.end(), *iterBtn) == m_listIterBtn.end())
					{
						(*iterBtn)->runAction(CCFadeOut::actionWithDuration(m_actionDelay));
					}
				}
				
			}
			break;

		case SHUT_FadeOutSmall:
			{
				if(NULL != m_pTarget)
				{
					m_pSprBack->runAction(CCSequence::actions(
						CCFadeOut::actionWithDuration(m_actionDelay),
						CCCallFunc::actionWithTarget(this, callfunc_selector(CCocosDialog::OnShut)),
						CCCallFunc::actionWithTarget(m_pTarget, m_selector),
						NULL));
					m_pTarget = NULL;
				}
				else
				{
					m_pSprBack->runAction(CCSequence::actions(
						CCFadeOut::actionWithDuration(m_actionDelay),
						CCCallFunc::actionWithTarget(this, callfunc_selector(CCocosDialog::OnShut)),
						NULL));
				}

				m_pSprBack->runAction(CCScaleTo::actionWithDuration(m_actionDelay, 0.01f, 0.01f));

				for(vector<CSpriteButton *>::iterator iterBtn = m_vBtns.begin(); iterBtn != m_vBtns.end(); iterBtn++)
				{
					if(find(m_listIterBtn.begin(), m_listIterBtn.end(), *iterBtn) == m_listIterBtn.end())
					{
						(*iterBtn)->runAction(CCFadeOut::actionWithDuration(m_actionDelay));
					}

				}

			}
			break;
		case SHUT_MOVETO:
			{
				if(NULL != m_pTarget)
				{
					m_pSprBack->runAction(CCSequence::actions(
						CCMoveTo::actionWithDuration(m_actionDelay, m_ptMoveTo),
						CCCallFunc::actionWithTarget(this, callfunc_selector(CCocosDialog::OnShut)),
						CCCallFunc::actionWithTarget(m_pTarget, m_selector),
						NULL));
					m_pTarget = NULL;
				}
				else
				{
					m_pSprBack->runAction(CCSequence::actions(
						CCMoveTo::actionWithDuration(m_actionDelay, m_ptMoveTo),
						CCCallFunc::actionWithTarget(this, callfunc_selector(CCocosDialog::OnShut)),
						NULL));
				}
			}
			break;
		}
	}

	void SetTarget(SelectorProtocol* pSelectorTarget, SEL_CallFunc selector)
	{
		m_pTarget  = pSelectorTarget;
		m_selector = selector;
	}

	void EnableButtons(bool bEnable)
	{
		for(vector<CSpriteButton *>::iterator iterBtn = m_vBtns.begin(); iterBtn != m_vBtns.end(); iterBtn++)
		{
			if(find(m_listIterBtn.begin(), m_listIterBtn.end(), *iterBtn) == m_listIterBtn.end())
			{
				(*iterBtn)->SetIsEnable(bEnable);
			}
			
		}
	}

	void SetPosition(cocos2d::CCPoint pt)
	{
		m_pSprBack->setPosition(pt);
	}

	void SetActionDuation(cocos2d::ccTime duration) {m_actionDelay = duration;}
	void SetMoveToPos(cocos2d::CCPoint ptPos) {m_ptMoveTo = ptPos;}

private:
	void OnPop()
	{
		EnableButtons(true);
	}

	void OnShut()
	{
		
		m_pSprBack->setIsVisible(false);
	}

	

private:
	CCNode   *m_pParent;
	CCSprite *m_pSprBack;
	int       m_zorder;
	SelectorProtocol *m_pTarget;
	SEL_CallFunc      m_selector;
	float     m_actionDelay;
	cocos2d::CCPoint m_ptMoveTo;


	vector<CSpriteButton *> m_vBtns;
	list<CSpriteButton *> m_listIterBtn;
	vector<CCocosSlide *> m_vSlide;
};
#endif